import time, traceback, sys, os
from threading import RLock
from support.ui.console import Log, NullDev
from support.ui.progress.column import CountColumn
from support.ui.progress.progress import SmartProgress
from support.ui.panel.panel import ClockPanel, CopyrightPanel, LogPanel
from rich.live import Live
from rich.layout import Layout
from rich.panel import Panel
from rich.table import Table
from rich.console import Console
from rich.progress import BarColumn, DownloadColumn, Progress, TextColumn, TimeRemainingColumn, ProgressColumn
from typing import (
        IO,
        TYPE_CHECKING,
        Any,
        Callable,
        Dict,
        Iterable,
        List,
        Mapping,
        NamedTuple,
        Optional,
        TextIO,
        Tuple,
        Type,
        Union,
        cast,
    )

class DashBoard:
    def __init__(self, title: str="Welcome Use Ray's DashBoard v1.0"):
        self.jobsProgress = None
        self.overallProgress = None
        self.logRedirect = None
        self.live = None
        self._lock = RLock()
        self.__initProgress()
        self.layout = self.__initLayout(title)
        self.mainProgressId = self.overallProgress.restProgress(description="All Jobs", total=0)

    def startProgress(self, description, total):
        id = self.jobsProgress.restProgress(description=description, total=total)
        # self.jobsProgress.updateTaskStatus(id)
        return id

    def stopJobsProgress(self, id):
        self.jobsProgress.stop_task(id)

    def updateMainProgress(self, total: Optional[int] = None, advance: Optional[float] = None):
        self.overallProgress.updateTaskStatus(self.mainProgressId, advance=advance, total=total)

    def updateJobsProgress(self, taskid, *, total: Optional[float] = None, advance: Optional[float] = None):
        self.jobsProgress.updateTaskStatus(taskid, advance=advance, total=total)

    def __initProgress(self):
        self.overallProgress = SmartProgress(TextColumn("[progress.description]{task.description}"), CountColumn(), BarColumn(), TextColumn("[progress.percentage]{task.percentage:>3.0f}%"))
        self.jobsProgress = SmartProgress(TextColumn("{task.description}", justify="left"),"|",DownloadColumn(),BarColumn(bar_width=None),"|",TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),"|",TimeRemainingColumn())
        self.jobsProgress.addOnFinishedListener(self.overallProgress.updateTaskStatus)

    def __initLayout(self, title):
        layout = Layout(name="root")
        layout.split(
            Layout(name="header", size=3),
            Layout(name="main", ratio=1),
            Layout(name="copyright", size=9),
        )
        layout["main"].split_row(
            Layout(name="info", ratio=2),
            Layout(name="progress", ratio=1)
        )
        layout["progress"].split(
            Layout(name="overall", size=3),
            Layout(name="jobs", ratio=1)
        )
        self.logRedirect = LogPanel()
        # Log.logRedirect = NullDev()
        Log.logRedirect = self.logRedirect
        layout["info"].update(self.logRedirect)
        layout["copyright"].update(CopyrightPanel())
        layout["header"].update(ClockPanel(title, "white on blue"))
        layout["overall"].update(Panel(self.overallProgress, title="Overall Progress", border_style="orange4"))
        layout["jobs"].update(Panel(self.jobsProgress, title="[ Jobs Progress ]", border_style="green"))
        return layout

    def show(self):
        self.live = Live(self.layout, refresh_per_second=1, screen=True, auto_refresh=False)
        #self.live = Live(self.layout, refresh_per_second=4, screen=True)
        self.live.start(True)

    def update(self):
        self._lock.acquire()
        if(self.live is not None):
            self.live.update(self.layout)
        self._lock.release()

    def hiden(self):
        if(self.live is not None):
            self.live.stop()
